#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>

#define MBUF_SIZE 32

int main(int argc, char **argv)
{
    // Initialize EAL
    int ret = rte_eal_init(argc, argv);
    if (ret < 0) {
        return -1;
    }

    printf("firstcode\n");
    // mem pool
    struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("firstcode", 1024, 0, 0, 
        RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());

    if (!mbuf_pool) {
        rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
    }

    // port set
    int gPortID = 0;
    uint16_t nb_rx_q = 1;
    uint16_t nb_tx_q = 0;
    struct rte_eth_conf port_conf_default = {
        .rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN}
    };

    rte_eth_dev_configure(gPortID, nb_rx_q, nb_tx_q, &port_conf_default);

    rte_eth_rx_queue_setup(gPortID, 0, 128, 
            rte_eth_dev_socket_id(gPortID), NULL, mbuf_pool);  // rx 是环形队列
    
    rte_eth_dev_start(gPortID);

    // rte_eth_promiscuous_enable(gPortID); // 开启混杂模式

    while (1)
    {
        struct rte_mbuf *mbufs[MBUF_SIZE];
        unsigned nrecv = rte_eth_rx_burst(gPortID, 0, mbufs, MBUF_SIZE);
        if (nrecv > MBUF_SIZE){
            rte_exit(EXIT_FAILURE, "rte_eth_rx_burst error\n");
        }

        unsigned i = 0;
        for (; i < nrecv; i++)
        {
            struct rte_ether_hdr *ehdr = rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr *);
            if (ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
                continue;
                // 不是ip协议，不处理了，也可以通过kni写回内核
            }
            struct rte_ipv4_hdr *iphdr = rte_pktmbuf_mtod_offset(mbufs[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
            if (iphdr->next_proto_id == IPPROTO_UDP) {
                struct rte_udp_hdr *udphdr = (struct rte_udp_hdr *)(iphdr + 1);
                uint16_t length = udphdr->dgram_len; 
                *((char *)udphdr + sizeof(struct rte_udp_hdr) + length - 1) = '\0';
                printf("udp: %s\n", (char*)(udphdr + 1));
            }
        }

    }
    
    return 0;
}